import { Element, useEditor, useNode } from '@craftjs/core';
import { ComponentType, FC } from 'react';
import { NodeBox } from '../../../components/NodeBox';

/** 包装组件 */
export const warpComponentFn = <T extends object>(
  name: string,
  Component: ComponentType<T>,
  Settings: ComponentType,
  defaultProps: T | (() => T),
  config: TConfig = {},
) => {
  const NewComponent: FC<T> & { craft: object; toolbox: TToolbox; config: TConfig } = (
    props: T,
  ) => {
    const { nodeId } = useNode((node) => {
      return {
        nodeId: node.id,
      };
    });

    return (
      <NodeBox id={nodeId} style={config.style}>
        <Component {...props} />
      </NodeBox>
    );
  };

  NewComponent.config = config;
  NewComponent.displayName = name;
  // 拖入dom关联
  NewComponent.toolbox = (
    create: ReturnType<typeof useEditor>['connectors']['create'],
    dom: HTMLElement,
  ) => {
    const Com = NewComponent as unknown as ComponentType;
    if (config.isContainer) {
      return create(
        dom,
        <Element
          {...(typeof defaultProps === 'function'
            ? defaultProps()
            : defaultProps)}
          is={Com}
          canvas
        />,
      );
    }
    return create(
      dom,
      <Com
        {...(typeof defaultProps === 'function'
          ? defaultProps()
          : defaultProps)}
      />,
    );
  };
  NewComponent.craft = {
    displayName: name,
    props:
      typeof defaultProps === 'function' ? defaultProps() : defaultProps || {},
    related: {
      settings: Settings,
    },
  };

  return NewComponent;
};

type TToolbox = (
  create: ReturnType<typeof useEditor>['connectors']['create'],
  dom: HTMLElement,
) => HTMLElement;

type TConfig = {
  isContainer?: boolean;
  /** 中文名称 */
  name?: string;
  /** 隐藏组件 */
  hidden?: boolean;
  /**
   * 排序
   * @default 99
   */
  sort?: number;
  style?: React.CSSProperties;
};
